package com.transsion.clouddemo.core.Custom

import android.accounts.AuthenticatorException
import android.accounts.NetworkErrorException
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.core.content.ContextCompat.startActivity
import com.transsion.clouddemo.CloudApplication
import com.transsion.lib_http.RetrofitBuildHelper
import com.transsion.lib_http.UtilsSdkInit
import com.transsion.lib_http.bean.BaseResult
import com.transsion.lib_http.utilcode.util.Utils
import com.transsion.lib_interface.api.ICloudServerService
import com.transsion.lib_interface.api.IClubCallback
import com.transsion.palmsdk.PalmAuthParam
import com.transsion.palmsdk.PalmID
import com.transsion.palmsdk.Scope
import com.transsion.palmsdk.data.PalmAuthResult
import com.transsion.clouddemo.CloudApplication.Companion.context
import com.transsion.clouddemo.CloudApplication.Companion.initCloudSdk
import com.transsion.clouddemo.MainActivity
import com.transsion.clouddemo.R
import com.transsion.clouddemo.core.Custom.utils.SPUtils
import com.transsion.clouddemo.core.Custom.utils.ToastUtils
import com.transsion.clouddemo.core.config.ConfigFragment.Companion.KEY_ENV
import com.transsion.clouddemo.core.network.CloudHttpService
import com.transsion.clouddemo.core.network.model.UserBean
import com.transsion.widgetslib.dialog.PromptDialog
import kotlinx.coroutines.isActive
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

object TransIDManager {


    private const val APP_ID = "infinix-cloud"
    private var isInit = false
    var accessToken: String = ""
    var isLoggingIn: Boolean = false
    var openId: String = ""

    //sp
    private const val KEY_OPEN_ID = "cloud_openId"
    const val KEY_ACCESS_TOKEN = "cloud_accessToken"
    private const val KEY_UNIQUE_ID = "cloud_server_uniqueId"

    //userdata
    var userBean: UserBean? = null

    var uniqueId: String = ""

    val palmIdInstance: PalmID by lazy {
        PalmID.instance(context)
    }

    fun init(mode: Int) {
        if (isInit) {
            return
        }
        isInit = true
        val pm = PalmAuthParam.Builder().setAppid(APP_ID).setScopes(arrayOf(Scope.INFO_ALL))
            .setServerMode(mode)//云服务Demo设置的是测试环境
            .requestToken() // 返回数据类型，登录完成后默认返回auth code，调用之后会返回access token
            .bindTransID(true) // 是否绑定OS账号App，绑定之后，若OS账号退出，业务方App也会自动退出
            .showPrevLogin(false) // 设置在系统PalmID已登录时是否弹出允许切换账号的登录弹框
            .build()
        PalmID.createInstance(context, pm).apply {
            addLoggedListener { isLogged ->
                if (!isLogged) {
                    // 监听到系统账号退出，清除缓存
                    clearUserInfo()
                }
            }
        }
    }

    /**
     * 登录，返回accessToken
     */
    suspend fun authorize(activity: Context, silentMode: Boolean = false): String {

        if (accessToken.isEmpty()) {
            accessToken = SPUtils.getString(KEY_ACCESS_TOKEN).toString()
            openId = SPUtils.getString(KEY_OPEN_ID).toString()
        }
        //如果token没有过期则直接返回
        if (accessToken.isNotEmpty() && openId.isNotEmpty() && palmIdInstance.tokenExpiredTs > 0) {
            return accessToken
        }

        isLoggingIn = true
        return suspendCoroutine {
            palmIdInstance.authorize(activity, silentMode, object : PalmID.IPalmAuthListener {
                override fun onSuccess(authResult: PalmAuthResult?) {
                    if (authResult != null) {
                        Log.e("zhangxin","授权成功了哦")
                        // 统一处理access_token和openId
                        accessToken = authResult.accessToken
                        openId = authResult.openid
                        SPUtils.putString(KEY_OPEN_ID, openId)
                        SPUtils.putString(KEY_ACCESS_TOKEN, accessToken)
                        it.resume(accessToken)
                    } else {
                        it.resumeWithException(Exception(activity.getString(R.string.user_login_failed)))
                    }
                    isLoggingIn = false
                }

                override fun onCancel() {
                    isLoggingIn = false
                    Log.e("zhangxin","用户取消了哦")
                    if (it.context.isActive) {
                        it.resumeWithException(Exception(activity.getString(R.string.user_login_canceled)))
                    }
                }

                override fun onFailure(errorCode: Int, errorMessage: String?) {
                    isLoggingIn = false
                    val exception: Exception = when (errorCode) {
                        40103 -> {
                            // 网络未连接/请求超时等
                            NetworkErrorException(errorMessage)
                        }

                        401, 403 -> {
                            SPUtils.clearAll()
                            AuthenticatorException(errorMessage)
                        }

                        else -> {
                            Exception(
                                errorMessage ?: activity.getString(R.string.user_login_failed)
                            )
                        }
                    }
                    if (it.context.isActive) {
                        Log.e("zhangxin","errorCode:$errorCode")
                        Log.e("zhangxin","errorMessage:$errorMessage")
                        it.resumeWithException(exception)
                    }
                }
            })

        }
    }

    fun queryTokenExpired(): Boolean {
        return palmIdInstance.tokenExpiredTs == 0L
    }

    suspend fun loginByToken(): BaseResult<UserBean> {
        val httpService = RetrofitBuildHelper.create(CloudHttpService::class.java)
        val result = httpService.loginByToken()
        // 统一处理用户信息
        if (result.success()) {
            userBean = result.data
        } else if (result.needLogin()) {
            refreshToken()
        }
        return result
    }

    suspend fun refreshToken(): String {
        if (palmIdInstance.tokenExpiredTs > 0) {
            return ""
        }
        return suspendCoroutine {
            palmIdInstance.refreshToken(object : PalmID.IPalmApiListener<String> {
                override fun onSuccess(token: String?) {
                    if (!token.isNullOrEmpty()) {
                        accessToken = token
                        SPUtils.putString(KEY_ACCESS_TOKEN, accessToken)
                        UtilsSdkInit.accessToken = token
                        it.resume(token)
                    } else {
                        it.resumeWithException(
                            Exception(
                                context.getString(R.string.user_login_failed)
                            )
                        )
                    }
                }

                override fun onFailure(errorCode: Int, errorMessage: String?) {
                    isLoggingIn = false
                    val exception: Exception = when (errorCode) {
                        40104 -> {
                            // 网络未连接/请求超时/服务器异常
                            NetworkErrorException(errorMessage)
                        }

                        40105 -> {
                            // 用户未登录/登录过期
                            clearUserInfo()
                            Exception(
                                errorMessage ?: Utils.getApp().getString(R.string.user_login_failed)
                            )
                        }
                        else -> {
                            Exception(
                                errorMessage ?: Utils.getApp().getString(R.string.user_login_failed)
                            )
                        }
                    }
                    it.resumeWithException(exception)
                }


            })

        }
    }

    fun logout(activity: Activity, mode: Int) {
        palmIdInstance.logout(false, object : PalmID.IPalmApiListener<Boolean> {
            override fun onSuccess(p0: Boolean?) {
                Log.e("zhangxin", "账号已退出")
                startActivityAndService(activity, mode)

                SPUtils.putString(KEY_ENV, if (mode==PalmID.SERVER_ONLINE) "release" else "test")
                showLoginErrorDialog(activity)

//                val intent = Intent(context, MainActivity::class.java).apply {
//                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
//                }
//                context.startActivity(intent)
            }

            override fun onFailure(p0: Int, p1: String?) {
                ToastUtils.showShort(context, "账号退出失败")
                Log.e("zhangxin", "账号退出失败")
            }

        })

    }

    fun showLoginErrorDialog(activity: Activity) {
       PromptDialog.Builder(activity)
            .setTitle(R.string.app_name)
            .setMessage(R.string.cloud_relogin_message)
            .setPositiveButton(R.string.cloud_login_positive) { _, _ ->
                val intent=Intent(activity,MainActivity::class.java).apply {
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
                    putExtra("isInit", true)
                }
                activity.startActivity(intent)
            }
            .setCanceledOnTouchOutside(false)
            .setNegativeButton(R.string.cloud_login_cancel) { _, _ ->
                activity.finish()
            }
            .show()
    }

    //切换账号的环境
    fun startActivityAndService(context: Context, mode: Int) {
        // 启动 Activity
        val activityIntent = Intent().apply {
            setClassName(
                "tech.palm.id",
                "tech.palm.lib.net.DumpActivity"
            )
            putExtra("caller_package", CloudApplication.PKG_NAME)  // 手动传递调用方的包名
            if (mode == PalmID.SERVER_ONLINE) {
                putExtra("mode", "release")
            }else if (mode == PalmID.SERVER_TEST) {
                putExtra("mode", "test")
            }
            flags = Intent.FLAG_ACTIVITY_NO_HISTORY
        }
        context.startActivity(activityIntent)
    }

    /**
     * 二次授权：用云服务token帮助业务方获取token
     */
    fun bizAuthorize(bizAppId: String, callback: IClubCallback?) {
        //账号未登录
        if (!palmIdInstance.isOSLoggedIn){
            callback?.callback(null)
            return
        }
        val pm = PalmAuthParam.Builder().setAppid(bizAppId).setScopes(arrayOf(Scope.INFO_ALL))
            .requestToken() // 返回数据类型，登录完成后默认返回auth code，调用之后会返回access token
            .build()
        palmIdInstance.authorize(pm, object : PalmID.IPalmAuthListener {
            override fun onSuccess(authResult: PalmAuthResult?) {
                if (authResult != null) {
                    val bundle = Bundle()
                    if (uniqueId.isEmpty()){
                        uniqueId = SPUtils.getString(KEY_UNIQUE_ID).toString()
                    }
                    bundle.putString(ICloudServerService.KEY_USER_UNIQUE_ID, uniqueId)
                    bundle.putString(bizAppId, authResult.accessToken)
                    callback?.callback(bundle)
                } else {
                    callback?.callback(null)
                }
            }

            override fun onCancel() {
                callback?.callback(null)
            }

            override fun onFailure(errorCode: Int, errorMessage: String?) {
                callback?.callback(null)
            }
        })
    }

    public fun clearUserInfo() {
        accessToken = ""
        openId = ""
        userBean = null
        SPUtils.putString(KEY_OPEN_ID, "")
        SPUtils.putString(KEY_ACCESS_TOKEN, "")
    }


}